home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 2
/
Gold Medal Software Volume 2 (Gold Medal) (1994).iso
/
prog
/
pcl4p40.arj
/
TERM.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-10-21
|
12KB
|
348 lines
(**********************************************)
(* *)
(* TERM.PAS March 1993 *)
(* *)
(* TERM is a simple terminal emulator which *)
(* features XMODEM, YMODEM, YMODEM-G, and *)
(* ASCII file transfer. *)
(* *)
(* Do NOT select YMODEM-G when using a null *)
(* modem cable unless you are certain that *)
(* RTS & CTS are reversed -- which is *)
(* usually not true. *)
(* *)
(* Remember that you cannot send or receive *)
(* binary files with ascii protocol - this *)
(* includes many word processor file formats *)
(* such as used by Wordstar. *)
(* *)
(* This program is donated to the Public *)
(* Domain by MarshallSoft Computing, Inc. *)
(* It is provided as an example of the use *)
(* of the Personal Communications Library. *)
(* *)
(**********************************************)
{$I DEFINES.PAS}
program term;
uses term_io, modem_io, xymodem, xypacket, amodem, crc, crt, PCL4P;
const
SIO_BUFFER_SIZE = 2048;
Var (* globals *)
ResetFlag : Boolean;
Port : Integer;
SioBuffer : array[0..SIO_BUFFER_SIZE-1] of Byte;
function MatchBaud(BaudRate : LongInt) : Integer;
Label 999;
const
BaudRateArray : array[1..10] of LongInt =
(300,600,1200,2400,4800,9600,19200,38400,57600,115200);
var
i : Integer;
begin
for i := 1 to 10 do if BaudRateArray[i] = BaudRate then
begin
MatchBaud := i - 1;
goto 999
end;
(* no match *)
MatchBaud := -1;
999: end;
procedure MyHalt( Code : Integer );
var
RetCode : Integer;
begin
if Code < 0 then SayError( Code,'Halting' );
if ResetFlag then RetCode := SioDone(Port);
writeln('*** HALTING ***');
Halt;
end;
(* main program *)
label 500;
const
NAK = $15;
WrongBaud1 = 'Cannot recognize baud rate';
WrongBaud2 = 'Must be 300,600,1200,2400,4800,9600,19200,38400,57600, or 155200';
var
Filename : String20;
ResultMsg : String20;
c : Char;
BaudRate : LongInt;
BaudCode : Integer;
Protocol : Char;
Buffer : BufferType;
RetCode : Integer;
TheByte : Char;
i : Integer;
MenuMsg : String40;
StatusMsg : String40;
GetNameMsg: String40;
OneKflag : Boolean;
NCGbyte : Byte;
BatchFlag: Boolean;
Flag : Boolean;
Version : Integer;
TermChar : Byte;
CharPace : Integer;
Timeout : Integer;
EchoFlag : Boolean;
begin (* main program *)
InitCRC;
TextMode(BW80);
ClrScr;
Window(1,1,80,24);
ResetFlag := FALSE;
Protocol := 'X';
OneKflag := FALSE;
NCGbyte := NAK;
BatchFlag := FALSE;
MenuMsg := 'Q)uit P)rotocol S)end R)eceive: ';
GetNameMsg := 'Enter filename: ';
StatusMsg := 'COM? X "ESC for menu" ';
(* fetch PORT # from command line *)
if ParamCount <> 2 then
begin
writeln('USAGE: "TERM <port> <buadrate>" ');
halt;
end;
Val( ParamStr(1),Port, RetCode );
if RetCode <> 0 then
begin
writeln('Port must be 1 to 4');
Halt;
end;
(* COM1 = 0, COM2 = 1, COM3 = 2, COM4 = 3 *)
Port := Port - 1;
Val( ParamStr(2),BaudRate, RetCode );
if RetCode <> 0 then
begin
writeln(WrongBaud1);
writeln(WrongBaud2);
Halt;
end;
BaudCode := MatchBaud(BaudRate);
if BaudCode < 0 then
begin
writeln(WrongBaud1);
writeln(WrongBaud2);
halt;
end;
(* patch up status message *)
StatusMsg[4] := chr($31+Port);
Insert(ParamStr(2),StatusMsg,8);
WriteMsg(StatusMsg,40);
if (Port<COM1) or (Port>COM4) then
begin
writeln('Port must be 1 to 4');
Halt
end;
(*** custom configuration: 4 port card
RetCode := SioIRQ(COM3,IRQ2);
RetCode := SioIRQ(COM4,IRQ2);
***)
(*** custom configuration: DigiBoard PC/8
RetCode := SioPorts(8,COM1,$140);
RetCode := SioUART(Port,$100+8*Port) ;
if RetCode < 0 then MyHalt( RetCode );
RetCode := SioIRQ(Port,IRQ5) ;
if RetCode < 0 then MyHalt( RetCode );
***)
(* setup 2K receive buffer *)
RetCode := SioRxBuf(Port, Ofs(SioBuffer), Seg(SioBuffer), Size2K);
if RetCode < 0 then MyHalt( RetCode );
(* reset port *)
RetCode := SioReset(Port,BaudCode);
(* if error then try one more time *)
if RetCode <> 0 then RetCode := SioReset(Port,BaudCode);
(* Was port reset ? *)
if RetCode <> 0 then
begin
writeln('Cannot reset COM',Port+1);
MyHalt( RetCode );
end;
(* Port successfully reset *)
ResetFlag := TRUE;
ClrScr;
(* show logon message *)
WriteLn('TERM 10/18/93');
Version := SioInfo('V');
WriteLn('Library Version ',Version div 16,'.',Version mod 16);
(* specify parity, # stop bits, and word length for port *)
RetCode := SioParms(Port, NoParity, OneStopBit, WordLength8);
if RetCode < 0 then MyHalt( RetCode );
RetCode := SioRxFlush(Port);
if RetCode < 0 then MyHalt( RetCode );
(* set FIFO level if have INS16550 *)
RetCode := SioFIFO(Port, LEVEL_8);
if RetCode > 0 then writeln('INS16550 detected');
(* set DTR & RTS *)
RetCode := SioDTR(Port,SetPort);
RetCode := SioRTS(Port,SetPort);
{$IFDEF RTS_CTS_CONTROL}
(* enable RTS/CTS flow control *)
RetCode := SioFlow(Port,3*18);
WriteLn('Hardware flow control enabled');
Write('CTS = ');
if SioCTS(Port) > 0 then WriteLn('ON') else WriteLn('OFF');
{$ENDIF}
{$IFDEF AT_COMMAND_SET}
(* send initialization string to modem *)
SendTo(Port,'!AT!!~');
SendTo(Port,'!AT E1 S7=60 S11=60 V1 X1 Q0 S0=1!');
if WaitFor(Port,'OK') then writeln('MODEM ready')
else writeln('WARNING: Expected OK not received');
{$ENDIF}
(* begin terminal loop *)
WriteMsg(StatusMsg,40);
LowVideo;
while TRUE do
begin (* while TRUE *)
(* did user press Ctrl-BREAK ? *)
if SioBrkKey then
begin
writeln('User typed Ctl-BREAK');
RetCode := SioDone(Port);
Halt;
end;
(* anything incoming over serial port ? *)
RetCode := SioGetc(Port,0);
if RetCode < -1 then MyHalt( RetCode );
if RetCode > -1 then write(chr(RetCode));
(* has user pressed keyboard ? *)
if KeyPressed then
begin (* keypressed *)
(* read keyboard *)
TheByte := ReadKey;
(* quit if user types ESC *)
if TheByte = chr($1b) then
begin (* ESC *)
WriteMsg(MenuMsg,1);
ReadMsg(ResultMsg,32,1);
c := UpCase(ResultMsg[1]);
case c of
'Q': (* QUIT *)
begin
WriteLn;
WriteLn('TERMINATING: User pressed <ESC>');
RetCode := SioDone(Port);
Halt;
end;
'P': (* PROTOCOL *)
begin
WriteMsg('A)scii X)modem Y)modem ymodem-G): ',1);
ReadMsg(ResultMsg,35,1);
c := UpCase(ResultMsg[1]);
case c of
'A': (* ASCII *)
begin
Protocol := 'A';
(* setup ascii parameters *)
TermChar := $18; (* CAN or control-X *)
CharPace := 5; (* 5 ms inter-byte delay *)
Timeout := 7; (* timeout after 7 seconds *)
EchoFlag := TRUE;(* local echo *)
WriteMsg('Protocol = ASCII',1);
end;
'X': (* XMODEM *)
begin
Protocol := 'X';
OneKflag := FALSE;
NCGbyte := NAK;
BatchFlag := FALSE;
WriteMsg('Protocol = XMODEM',1);
end;
'Y': (* YMODEM *)
begin
Protocol := 'Y';
OneKflag := TRUE;
NCGbyte := Ord('C');
BatchFlag := TRUE;
WriteMsg('Protocol = YMODEM',1);
end;
'G': (* YMODEM-G *)
begin
Protocol := 'G';
OneKflag := TRUE;
NCGbyte := Ord('G');
BatchFlag := TRUE;
WriteMsg('Protocol = YMODEM-G',1);
end;
end; (* case *)
StatusMsg[6] := Protocol;
WriteMsg(StatusMsg,40)
end;
'S': (* Send *)
begin
WriteMsg(GetNameMsg,1);
ReadMsg(Filename,16,20);
if Length(FileName) = 0 then goto 500;
if Protocol = 'A' then
begin
(* Ascii *)
Flag := TxAscii(Port,Filename,Buffer,CharPace,TermChar,Timeout,EchoFlag);
end
else
begin
(* XMODEM or YMODEM or YMODEM-G *)
Flag := TxyModem(Port,Filename,Buffer,OneKflag,BatchFlag);
if BatchFlag then
begin
(* send empty filename *)
Filename := '';
RetCode := SioDelay(5);
Flag := TxyModem(Port,Filename,Buffer,OneKflag,BatchFlag);
end
end
end; (* Send *)
'R': (* Receive *)
begin
if Protocol = 'A' then
begin
(* Ascii *)
WriteMsg(GetNameMsg,1);
ReadMsg(Filename,16,20);
if Length(FileName) = 0 then goto 500;
Flag := RxAscii(Port,Filename,Buffer,SIO_BUFFER_SIZE,TermChar,Timeout,EchoFlag);
end
else
begin
(* XMODEM or YMODEM or YMODEM-G *)
if BatchFlag then
repeat
WriteMsg('Ready for next file',1);
Filename := '';
Flag := RxyModem(Port,Filename,Buffer,NCGbyte,BatchFlag);
until KeyPressed or (Length(Filename) = 0)
else
begin (* not BatchFlag *)
WriteMsg(GetNameMsg,1);
ReadMsg(Filename,16,20);
if Length(Filename) = 0 then goto 500;
Flag := RxyModem(Port,Filename,Buffer,NCGbyte,BatchFlag);
end
end
end (* Receive *)
else WriteMsg('Bad response',1);
end; (* case *)
500:
end; (* ESC *)
(* send out over serial line *)
RetCode := SioPutc(Port, TheByte );
if RetCode < 0 then MyHalt( RetCode );
end (* keypressed *)
end (* while TRUE *)
end.